﻿using System;
using System.Collections.Generic;
using Ease.EaseNode.Runtime;
using Ease.EaseNode.Runtime.Param;
using System.Linq;

namespace Ease.EaseMission.Runtime
{
    public class MissionStageHandler : IMissionStageAgent
    {
        public IEaseNodeData Data { get; set; }

        private RunState currentState = RunState.NONE;

        public RunState CurrentState
        {
            get { return currentState; }
            set
            {
                if (currentState != value)
                {
                    OnRunStateChange?.Invoke(value);
                    OnValueChangeEvent?.Invoke(new StateChangeParam() { newState = (NodeState)value });
                }

                currentState = value;
            }
        }

        public event Action<RunState> OnRunStateChange;
        private List<MissionStepHandler> handlers = new List<MissionStepHandler>();
        private List<MissionStep> _steps = new List<MissionStep>();
        private MissionStage _missionStage;

        public MissionStageHandler(IEaseNodeData data)
        {
            Data = data;
            _missionStage = Data as MissionStage;
            CurrentState = RunState.NONE;
        }

        public void Start()
        {
            _steps.AddRange(_missionStage.Steps);
            TryStartNewAgent();
        }

        public void Reset()
        {
            CurrentState = RunState.NONE;
            foreach (var handler in handlers)
            {
                handler.Reset();
            }
        }


        public event Action<BaseChangeParam> OnValueChangeEvent;

        private void OnStateChange(RunState runState)
        {
            if (runState == RunState.FINISH)
                TryStartNewAgent();
        }

        private void TryStartNewAgent()
        {
            if (_steps.Count <= 0)
            {
                CurrentState = RunState.FINISH;
                foreach (var missionStepHandler in handlers)
                {
                    missionStepHandler.OnRunStateChange -= OnStateChange;
                }

                return;
            }

            CurrentState = RunState.ACTIVED;
            var step = _steps.First();
            _steps.RemoveAt(0);
            var stepHandler = GetHandler<MissionStepHandler>(step, handlers);
            stepHandler.OnRunStateChange -= OnStateChange;
            stepHandler.OnRunStateChange += OnStateChange;
            stepHandler.Start();
        }

        private T GetHandler<T>(IEaseNodeData data, List<T> handles) where T : class, IEaseNodeAgent
        {
            var target = handles.FirstOrDefault(x => x.Data == data);
            if (target != null)
            {
                return target;
            }
            else
            {
                target = data.CreateAgent() as T;
                handles.Add(target);
            }

            return target;
        }
    }
}